package com.tedu.api.list;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * 迭代器：打印集合元素【接口】
 * 集合提供自己一套输出集合元素的方法--迭代器【类似for，增强for】
 * 包位置：java.util
 * Iterator  接口
 * 该接口是集合接口，提供遍历元素的相关操作：问、取、删
 *
 * iterator()方法   返回值Iterator-----------Collection接口类已经存在的方法
 * 作用：获取一个用于遍历当前集合迭代器的实现类实例
 *
 * 遍历规则：问、取、删（山不是必须操作）
 */
public class Collection_iterator {
    @Test
    public void testIterator(){
        /**
         * 遍历集合方法
         * 1.普通for--遍历c1集合     集合：size（）
         * 语法：for(int i=0;i<c1.size();i++){}
         * 2.增强for--遍历c1集合    接受类型：Object
         * 语法：for（Object c:c1）{}
         * 3.Iterator迭代器--集合提供接口
         */
        //创建集合
        Collection c1=new ArrayList();
        c1.add("one");
        c1.add("two");
        c1.add("three");
        c1.add("four");
        c1.add("five");
        c1.add("six");
        //普通for  遍历集合
        //for(int i=0;i<c1.size();i++){
           // System.out.println("普通for:"+c1[i]);
       // }
        //增强for  遍历集合
        for(Object c:c1){
            System.out.println("增强for:"+c);
        }
        //iterator()获取一个用于遍历当前集合迭代器的实现类实例
        Iterator it=c1.iterator();//拿到集合所有元素
        //理解：拿到集合所有元素，封装迭代器创建对象过程--理解迭代器实例
        //使用Iterator--获取集合的某个元素，规则：问、取、删
        //Iterator接口--hasNext（）获取集合元素
        //思考：如果300个元素---循环while次数不固定
        while(it.hasNext()){//1.问：集合是否有元素
            //迭代器集合：获取元素    |     next（）元素    返回值：Object
            String str=(String) it.next();//2.取：获取集合元素
            System.out.println("迭代器"+str);
        }
        //迭代器是否改变集合的元素内容
        System.out.println(c1);
    }
    /**
     * *remove()  删除     Iterator送代器  √   增强for
     * 作用:副除相同的元素数据，提醒:问、取next方法【删】
     */
    @Test
    public void testRemove(){
        Collection c=new ArrayList();
        c.add("西游记");
        c.add("#");
        c.add("水浒传");
        //需求：通过迭代器删除#
        Iterator it=c.iterator();
        while(it.hasNext()){//问：有没有元素
            String str=(String)it.next();//取：有元素--打印元素
          //  c.remove("#");//Collection中存在remove（）
            //删除一定是迭代器
            if("#".equals(str)){//如果#是我们拿到的str元素中#
                it.remove();//那么，删除元素
            }
        }
        System.out.println("迭代器删除："+c);
    }
    /**
     *
     */
    @Test
    public void testFor() {
        Collection c = new ArrayList();
        c.add("西游记");
        c.add("#");
        c.add("水浒传");
        for (Object o : c) { //类型类型引用:集合引用

            if("#".equals(o)){
            c.remove(o);
            }
            System.out.println("删除集合元素："+c);
        }
        }
        /**
         *   E   element  泛型   JDK1.5新特性
         *   结合集合出现，约束集合的使用的类型【基本数据类型、引用类型、包装类】
         *   泛型的原型：Object，泛型是编译器认可的，JVM虚拟机不认可
         *   使用泛型是告诉编译器应该把泛型当成Object类型执行，便于编译器检查
         *   类型以及自动造型操作
         *
         *   泛型使用：
         *   Collection<类型：基本类型、引用类型 、包装类>c
         *       =new ArrayList<类型：基本类型、引用类型 、包装类>（）：
         *
         *       JDK1.7泛型使用
         *       Collection<类型：基本类型、引用类型 、包装类>c
         *        =new ArrayList<>();
         *
         *        Collection<类型：？>c
         *        =new ArrayList<>
         *           Collection<类型：？extends/super 父类/接口/类>c
         *           =new ArrayList<>()
         *           优点：保证类型安全
         */
        @Test
    public void testType(){
            //针对泛型自动推导
            Collection<String> c=new ArrayList<String>();
           // c1.add(null);//结论：
            c.add("123");c.add("456");c.add("789");
            Iterator<String> it=c.iterator();
            while(it.hasNext()){
                String str=it.next();
                System.out.println(str);
            }
        }

    }




    //--限定集合传入对应类型
class Fruit{
     private String name;//成员变量

        public Fruit(String name) {//有参构造器
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }
class Apple extends Fruit{

    public Apple() {
        super("苹果");//调用父类有参构造器，传入name名称
    }
}
class Orange extends Fruit{

    public Orange() {
        super("橙子");//调用父类有参构造器，传入name名称
    }
}
//测试类--泛型上界
class TestJob{
    //泛型上界   1.定义方法,制定泛型规则--集合中类型约定为Apple与Orange
    public static void printFruit(Collection<? extends Fruit> fruits){
        //2.增强for循环打印：集合中类型约定为Apple与Orange
        for(Fruit fruit:fruits){
            //3.方法能进入:Apple与Orange--打印名字
            System.out.println(fruit.getName());
        }
    }
//主方法：测试功能
    public static void main(String[] args) {
        Collection<Apple> apples=new ArrayList<>();
        apples.add(new Apple());//集合对象添加：Apple对象
        Collection<Orange> oranges=new ArrayList<>();
        oranges.add(new Orange());//集合对象添加：Orange对象
        printFruit(apples);//测试打印出苹果
        printFruit(oranges);
        //假设：西瓜
       // Collection<String> strings=new ArrayList<>();
       // strings.add(new String());
       // printFruit(strings);
    }
}

